package main

import (
	"bufio"
	"errors"
	"fmt"
	"os"
)

/**
	被 defer 修饰的代码确保在函数结束时发生
	参数在 defer 语句时计算
	defer 列表为后进先出

	一般使用场景
	Open/Close
	Lock/Unlock
	PrintHeader/PrintFooter

 */

func tryDefer() {
	// defer 关键字表示，在这个函数结束之前执行
	// defer 不管是 return 还是 panic 抛异常，都会执行
	// 同时出现 defer 关键字，那么先输出的是2而不是1，因为有个入栈的操作，在最上面的先执行
	defer fmt.Println(1)
	defer fmt.Println(2)

	fmt.Println(3)
}

func printDefer()  {
	for i := 0; i < 100 ; i++  {
		// 在程序结束的时候，才执行这句话
		defer fmt.Println(i)
		if i == 30 {
			panic("抛出一个异常！")

		}
	}
}

// 如果有异常抛出
func printDefers() (i int,err error) {
	for i := 0; i < 100 ; i++  {
		// 在程序结束的时候，才执行这句话
		defer fmt.Println(i)
		if i == 30 {
			// panic("抛出一个异常！")
			return 0, errors.New("抛出一个异常！")
		}
	}

	return i, nil
}

// 写入文件
func writeFile(filename string){
	file, err := os.Create(filename)
	if err != nil {
		 panic(err)
	}
	defer file.Close()

	wirte := bufio.NewWriter(file)
	// 刷新缓冲区，表示把内容真正写入到文件
	defer wirte.Flush()

	for i := 0; i < 20; i++  {
		// 写入数据
		fmt.Fprintln(wirte, i)
	}


}

func main()  {
	tryDefer()
	writeFile("1b.txt")
}

